"""
课后服务管理模块
负责实际的预定、取消、查询等业务逻辑
"""
import uuid
from typing import List, Optional, Dict, Any
from datetime import datetime
from slots import BookingSlots, ServiceType


class Booking:
    """预定记录类"""
    
    def __init__(
        self,
        booking_id: str,
        student_name: str,
        service_type: ServiceType,
        date: str,
        time_slot: str,
        teacher_preference: Optional[str] = None,
        notes: Optional[str] = None,
        created_at: Optional[datetime] = None
    ):
        self.booking_id = booking_id
        self.student_name = student_name
        self.service_type = service_type
        self.date = date
        self.time_slot = time_slot
        self.teacher_preference = teacher_preference
        self.notes = notes
        self.created_at = created_at or datetime.now()
        self.status = "active"
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "booking_id": self.booking_id,
            "student_name": self.student_name,
            "service_type": self.service_type.value,
            "date": self.date,
            "time_slot": self.time_slot,
            "teacher_preference": self.teacher_preference,
            "notes": self.notes,
            "created_at": self.created_at.isoformat(),
            "status": self.status
        }
    
    def __str__(self) -> str:
        """字符串表示"""
        return f"""
预定编号: {self.booking_id}
学生姓名: {self.student_name}
服务类型: {self.service_type.value}
日期: {self.date}
时间段: {self.time_slot}
教师偏好: {self.teacher_preference or '无'}
备注: {self.notes or '无'}
状态: {self.status}
        """.strip()


class ServiceManager:
    """课后服务管理器"""
    
    def __init__(self):
        # 使用内存存储（实际应用中应使用数据库）
        self.bookings: Dict[str, Booking] = {}
    
    def create_booking(self, slots: BookingSlots) -> tuple[bool, str, Optional[Booking]]:
        """
        创建预定
        
        Args:
            slots: 填充完整的预定插槽
        
        Returns:
            (成功标志, 消息, 预定对象)
        """
        if not slots.is_complete():
            missing = ", ".join(slots.get_missing_slots())
            return False, f"信息不完整，缺少: {missing}", None
        
        # 检查时间冲突
        conflict = self._check_time_conflict(
            slots.date, 
            slots.time_slot, 
            slots.service_type
        )
        
        if conflict:
            return False, f"该时间段已有预定：{conflict.booking_id}", None
        
        # 生成预定ID
        booking_id = self._generate_booking_id()
        
        # 创建预定
        booking = Booking(
            booking_id=booking_id,
            student_name=slots.student_name,
            service_type=slots.service_type,
            date=slots.date,
            time_slot=slots.time_slot,
            teacher_preference=slots.teacher_preference,
            notes=slots.notes
        )
        
        self.bookings[booking_id] = booking
        
        success_msg = f"""
✅ 预定成功！

{booking}

请记住您的预定编号：{booking_id}
        """.strip()
        
        return True, success_msg, booking
    
    def cancel_booking(self, booking_id: str) -> tuple[bool, str]:
        """
        取消预定
        
        Args:
            booking_id: 预定编号
        
        Returns:
            (成功标志, 消息)
        """
        if booking_id not in self.bookings:
            return False, f"未找到预定编号：{booking_id}"
        
        booking = self.bookings[booking_id]
        
        if booking.status == "cancelled":
            return False, "该预定已被取消"
        
        booking.status = "cancelled"
        
        success_msg = f"""
✅ 已成功取消预定

预定编号: {booking_id}
学生姓名: {booking.student_name}
服务类型: {booking.service_type.value}
日期: {booking.date}
时间段: {booking.time_slot}
        """.strip()
        
        return True, success_msg
    
    def query_bookings(self, student_name: str) -> tuple[bool, str, List[Booking]]:
        """
        查询学生的预定
        
        Args:
            student_name: 学生姓名
        
        Returns:
            (成功标志, 消息, 预定列表)
        """
        student_bookings = [
            b for b in self.bookings.values()
            if b.student_name == student_name and b.status == "active"
        ]
        
        if not student_bookings:
            return False, f"未找到 {student_name} 的有效预定", []
        
        msg = f"📋 {student_name} 的预定列表：\n\n"
        for i, booking in enumerate(student_bookings, 1):
            msg += f"{i}. {booking}\n\n"
        
        return True, msg.strip(), student_bookings
    
    def list_all_bookings(self) -> tuple[bool, str, List[Booking]]:
        """
        列出所有有效预定
        
        Returns:
            (成功标志, 消息, 预定列表)
        """
        active_bookings = [
            b for b in self.bookings.values()
            if b.status == "active"
        ]
        
        if not active_bookings:
            return False, "当前没有任何预定", []
        
        msg = f"📋 所有预定列表（共 {len(active_bookings)} 条）：\n\n"
        for i, booking in enumerate(active_bookings, 1):
            msg += f"{i}. {booking}\n\n"
        
        return True, msg.strip(), active_bookings
    
    def get_booking(self, booking_id: str) -> Optional[Booking]:
        """获取单个预定"""
        return self.bookings.get(booking_id)
    
    def _generate_booking_id(self) -> str:
        """生成预定ID"""
        return f"BK{datetime.now().strftime('%Y%m%d')}{uuid.uuid4().hex[:6].upper()}"
    
    def _check_time_conflict(
        self, 
        date: str, 
        time_slot: str, 
        service_type: ServiceType
    ) -> Optional[Booking]:
        """
        检查时间冲突
        
        Args:
            date: 日期
            time_slot: 时间段
            service_type: 服务类型
        
        Returns:
            冲突的预定，如果没有冲突返回None
        """
        for booking in self.bookings.values():
            if (booking.status == "active" and
                booking.date == date and
                booking.time_slot == time_slot and
                booking.service_type == service_type):
                return booking
        
        return None
    
    def get_statistics(self) -> Dict[str, Any]:
        """获取统计信息"""
        active_count = sum(1 for b in self.bookings.values() if b.status == "active")
        cancelled_count = sum(1 for b in self.bookings.values() if b.status == "cancelled")
        
        service_type_count = {}
        for booking in self.bookings.values():
            if booking.status == "active":
                st = booking.service_type.value
                service_type_count[st] = service_type_count.get(st, 0) + 1
        
        return {
            "total_bookings": len(self.bookings),
            "active_bookings": active_count,
            "cancelled_bookings": cancelled_count,
            "service_type_distribution": service_type_count
        }
